﻿using System;
using System.Diagnostics;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace G.SL.Controls
{

    [TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
    [TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
    [TemplateVisualState(Name = "Focused", GroupName = "FocusStates")]
    [TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
    [StyleTypedProperty(Property = "FocusVisualStyle", StyleTargetType = typeof(Control))]
    public class HeaderedContentControl : ContentControl
    {


        public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(object), typeof(HeaderedContentControl), new PropertyMetadata(OnHeaderChanged));


        public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(HeaderedContentControl), new PropertyMetadata(OnHeaderTemplateChanged));


        public static readonly DependencyProperty FocusVisualStyleProperty =
            DependencyProperty.Register("FocusVisualStyle", typeof(Style), typeof(HeaderedContentControl), null);

        /// <summary>
        /// 头标题垂直方向的对齐方式
        /// </summary>
        public static readonly DependencyProperty HeaderVerticalAlignmentProperty = DependencyProperty.Register("HeaderVerticalAlignment", typeof(VerticalAlignment), typeof(HeaderedContentControl), new PropertyMetadata(VerticalAlignment.Center));
        /// <summary>
        /// 头标题停靠方向
        /// </summary>
        public static readonly DependencyProperty HeaderDirectorProperty = DependencyProperty.Register("HeaderDirector", typeof(Dock), typeof(HeaderedContentControl), new PropertyMetadata(Dock.Top));

        /// <summary>
        /// 头标题水平方向的对齐方式
        /// </summary>
        public static readonly DependencyProperty HeaderHorizontalAlignmentProperty = DependencyProperty.Register("HeaderHorizontalAlignment", typeof(HorizontalAlignment), typeof(HeaderedContentControl), new PropertyMetadata(HorizontalAlignment.Center));


        /// <summary>
        /// 头标题停靠方向
        /// </summary>
        public static readonly DependencyProperty HeaderMarginProperty = DependencyProperty.Register("HeaderMargin", typeof(Thickness), typeof(HeaderedContentControl), null);



        private static readonly DependencyProperty IsFocusedProperty =
            DependencyProperty.Register("IsFocused", typeof(bool), typeof(HeaderedContentControl), new PropertyMetadata(false, OnIsFocusedChanged));

        private static readonly DependencyProperty HasHeaderProperty =
            DependencyProperty.Register("HasHeader", typeof(bool), typeof(HeaderedContentControl), new PropertyMetadata(false));


        public HeaderedContentControl()
        {
            DefaultStyleKey = typeof(HeaderedContentControl);
            IsEnabledChanged += new DependencyPropertyChangedEventHandler(this.OnIsEnabledChanged);
        }


        public bool HasHeader
        {
            get
            {
                return (bool)GetValue(HasHeaderProperty);
            }
            private set
            {
                this.SetValue(HasHeaderProperty, value);
            }
        }


        public bool IsFocused
        {
            get { return (bool)GetValue(IsFocusedProperty); }
            protected set { this.SetValue(IsFocusedProperty, value); }
        }
        public VerticalAlignment HeaderVerticalAlignment
        {
            get { return (VerticalAlignment)this.GetValue(HeaderedContentControl.HeaderVerticalAlignmentProperty); }
            set { this.SetValue(HeaderedContentControl.HeaderVerticalAlignmentProperty, value); }
        }

        public HorizontalAlignment HeaderHorizontalAlignment
        {
            get { return (HorizontalAlignment)this.GetValue(HeaderedContentControl.HeaderHorizontalAlignmentProperty); }
            set { this.SetValue(HeaderedContentControl.HeaderHorizontalAlignmentProperty, value); }
        }

        public Thickness HeaderMargin
        {
            get { return (Thickness)this.GetValue(HeaderedContentControl.HeaderMarginProperty); }
            set { this.SetValue(HeaderedContentControl.HeaderMarginProperty, value); }
        }
        public Dock HeaderDirector
        {
            get { return (Dock)this.GetValue(HeaderedContentControl.HeaderDirectorProperty); }
            set { this.SetValue(HeaderedContentControl.HeaderDirectorProperty, value); }
        }

        public object Header
        {
            get
            {
                return GetValue(HeaderProperty);
            }
            set
            {
                SetValue(HeaderProperty, value);
            }
        }


        public Style FocusVisualStyle
        {
            get { return (Style)GetValue(FocusVisualStyleProperty); }
            set { SetValue(FocusVisualStyleProperty, value); }
        }


        public DataTemplate HeaderTemplate
        {
            get
            {
                return (DataTemplate)GetValue(HeaderTemplateProperty);
            }
            set
            {
                SetValue(HeaderTemplateProperty, value);
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.OnHeaderTemplateChanged(null, this.HeaderTemplate);
            this.OnHeaderChanged(null, this.Header);
            this.ChangeVisualState();

            if (this.Header == null)
            {
                this.Header = this.GetType().Name;
            }
        }


        protected internal virtual void ChangeVisualState()
        {
            this.ChangeVisualState(true);
        }


        protected internal virtual void ChangeVisualState(bool useTransitions)
        {
            if (this.IsEnabled)
            {
                VisualStateManager.GoToState(this, "Normal", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "Disabled", useTransitions);
            }

            if (this.IsFocused)
            {
                VisualStateManager.GoToState(this, "Focused", useTransitions);
            }
            else
            {
                VisualStateManager.GoToState(this, "Unfocused", useTransitions);
            }
        }



        protected internal virtual void OnIsEnabledChanged(DependencyPropertyChangedEventArgs e)
        {
            this.ChangeVisualState();
        }


        protected virtual void OnHeaderChanged(object oldHeader, object newHeader)
        {
        }


        protected virtual void OnHeaderTemplateChanged(DataTemplate oldHeaderTemplate, DataTemplate newHeaderTemplate)
        {
        }



        protected virtual void OnIsFocusedChanged(DependencyPropertyChangedEventArgs e)
        {
            this.ChangeVisualState();
        }


        protected override void OnGotFocus(RoutedEventArgs e)
        {
            if (e.OriginalSource != this)
            {
                return;
            }

            this.IsFocused = true;
            base.OnGotFocus(e);
        }


        protected override void OnLostFocus(RoutedEventArgs e)
        {
            this.IsFocused = false;
            base.OnLostFocus(e);
        }

        private static void OnHeaderChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            HeaderedContentControl control = (HeaderedContentControl)sender;
            Debug.Assert(control != null, "The property changed sender should be a HeaderedContentControl");

            control.HasHeader = e.NewValue != null;
            control.OnHeaderChanged(e.OldValue, e.NewValue);
        }

        private static void OnHeaderTemplateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((HeaderedContentControl)sender).OnHeaderTemplateChanged((DataTemplate)e.OldValue, (DataTemplate)e.NewValue);
        }

        private static void OnIsFocusedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            HeaderedContentControl headeredContentControl = sender as HeaderedContentControl;
            Debug.Assert(headeredContentControl != null, "The sender should be a headered content control");

            headeredContentControl.OnIsFocusedChanged(e);
        }

        private void OnIsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            this.OnIsEnabledChanged(e);
        }
    }
}
